#ifndef FILE_folder_H
#define FILE_folder_H

#include "inode.h"
#include "filehandle.h"

/// Returns ERR_PARAMETER_PROBLEM if the handle contain a file.
fs_ret_t fs_assertHandleIsFolder(FileSystemHandle_t *fsh,filehandleid_t handleId);

/// Returns ERR_PARAMETER_PROBLEM if the inode contain a file.
fs_ret_t fs_assertInodeIsFolder(FileSystemHandle_t *fsh,inodeid_t inodeId);

/// Creates a new folder.
/// \param noFather Shoud be true if it is the root. In this case, parentFolder won't be used.
fs_ret_t fs_newFolder(FileSystemHandle_t *fsh, inodeid_t parentFolder, inodeid_t* address, bool noFather, bool noSelf);

/// Delete the given folder.
///
/// Remove all the contained inodes recursively.
/// \warning Do not call it on it own, it shall be called in deleteInode.
fs_ret_t fs_deleteFolder(FileSystemHandle_t *fsh,inodeid_t folder);


/// Add the given inode to the folder.
///
/// Does not touch the refcount.
fs_ret_t fs_addInodeToFolder(FileSystemHandle_t *fsh,inodeid_t folder,inodeid_t toAdd,const char* itemName);

/// Remove the given file from the folder.
///
/// Does not touch the refcount.
/// Note that this is a quite heavy operation. The folder is first copied, and
/// then removed and replaced.
/// \note if the given inode does not exits, it will do all these actions to 
/// in the end do nothing.
fs_ret_t fs_removeInodeFromFolder(FileSystemHandle_t *fsh,inodeid_t folder,inodeid_t toRemove);

/// Creates a new file or folder and add it to the given inode.
/// \param[out] address The created inode address (set it to NULL if you don't care).
fs_ret_t fs_createItemInFolder(FileSystemHandle_t *fsh,inodeid_t folder,inodeid_t* address,const char* name, bool isFolder);

/// Return the next item of the folder.
///
/// You will know this is over when the function returns ERR_OUT_RANGE
/// This should be used to list the items of a folder.
/// \param cursor A indicator of the current position as input, updated with the
/// new position as output. To get the first item, it should be set to 0.
/// \param[out] itemName A 257 char array. Will contain the file name. May be NULL.
/// \param[out] itemAddress The inode id.
fs_ret_t fs_getNextFolderItem(FileSystemHandle_t *fsh,inodeid_t folder,filepos_t *cursor,char* itemName,inodeid_t* itemAddress);

/// Copy an file into the given folder.
///
/// If the file already exist, it overwrites it. Even if it is a folder.
///
/// \param[out] newInode The created file inodeid. Set to NULL if not needed.
fs_ret_t fs_copyFile(FileSystemHandle_t *fsh,inodeid_t from,inodeid_t toFolder,char *name,inodeid_t *newInode);

/// Copy an arborescence into the given folder (recursive, no choice).
///
/// Overwrites the items if they already exist. If a folder already exist,
/// contents are merged.
/// If a folder has the same name as a copied file, the folder is deleted.
/// If a file has the same name as a folder, it is deleted.
fs_ret_t fs_copyItemRecursive(FileSystemHandle_t *fsh,inodeid_t itemToCopy,inodeid_t toFolder,char *name,inodeid_t *newInode);

#endif // FILE_folder_H

